/*
	LCD Functions
	Updated: 20090304
	
	Created By: Jared Bayne
	E-Mail:		JaredNBayne@gmail.com
	Created On:	February 1st, 2008

	Purpose:	This file implements all of the functions
				for the built in LCD screen on the Olimex
				development board.


*/

void _E (void)
{
	EON;
	_delay_us(5);
	EOFF;
}	


void LCD_Ini(void)
{
	RSOFF;				
	_delay_ms(110);	
	PORTC=0b00110000;		
	_E();	
	_delay_ms(10);	
	PORTC=0b00110000;
	_E();
	_delay_ms(10);
	PORTC=0b00110000;
	_E();
	_delay_ms(10);
	PORTC=0b00100000;
	_E();
}      
    
//--------Send char to LCD-----------------------------
void SEND_CHAR (unsigned char c)
{    

	
	_delay_ms(LCD_CHAR_SPEED);              	    //Delay for LCD char
	data = 0b00001111 | c;			    //get upper nibble
	PORTC = (PORTC | 0b11110000) & data;        //set D4-D7
	RSON;		  			    //set LCD to data mode
	_E();
	data = c << 4;				    //get down nibble
	PORTC = (PORTC & 0b00001111) | data;	    //set D4-D7 (only PORTC4-PORTC7)
	RSON;					    //set LCD to data mode
	_E();
}               
    
//--------Send command to LCD-----------------------------
void SEND_CMD (unsigned char c)
{    

	
	_delay_ms(LCD_CHAR_SPEED);              	    //Delay for LCD char
	data = 0b00001111 | c;			    //get upper nibble
	PORTC = (PORTC | 0b11110000) & data;        //set D4-D7
	RSOFF;					    //set LCD to data mode
	_E();    
	data = c << 4;				    //get down nibble
	PORTC = (PORTC & 0b00001111) | data;	    //set D4-D7 (only PORTC4-PORTC7)
	RSOFF;					    //set LCD to data mode
	_E();
}                  



void lcddispmsgnew(char msg[], int length)
{
	/*This function will take in an array
	of characters and display it on the LCD
	screen.  It will always clear the display
	and start in the top left of the display*/
	
	char temp;
	
	SEND_CMD(CLR_DISP); 
 	_delay_ms(10);  
	SEND_CMD(DD_RAM_ADDR);
	
	for (int i=0 ; i!=length; i++)      			 //Send Message to LCD
	{
		temp=msg[i];
		SEND_CHAR(temp);  
		if (i == 15) SEND_CMD(DD_RAM_ADDR2);
	}

}

void lcdline2(void)
{

	SEND_CMD(DD_RAM_ADDR2);

}

void lcdline1(void)
{

	SEND_CMD(DD_RAM_ADDR);

}

void lcdclear(void)
{

	SEND_CMD(CLR_DISP);

}

void lcddispchar(char msg)
{
	/*This function will take in
	one character and display it
	to the LCD*/
	
	SEND_CHAR(msg);  


}
void lcddispint(int temp)
{
	//Displays integer on LCD
	//max:  32767
	//min: -32767
	
	int tenthousands, thousands, hundreds, tens, ones;
	
	while (temp>32767)
		temp-=1;
		
	while (temp<-32767)
		temp+=1;
	
	int temp_abs=temp;
	
	if (temp_abs<0)
		temp_abs=-temp_abs;
	tenthousands = (temp_abs/10000)+48;
	thousands=((temp_abs/1000)%10)+48;
	hundreds=((temp_abs/100)%10)+48;
	tens=((temp_abs/10)%10)+48;
	ones=(temp_abs%10)+48;
	
	
	if (tenthousands!='0')
	{
		if (temp<0)
			lcddispchar('-');
		lcddispchar(tenthousands);	
		lcddispchar(thousands);
		lcddispchar(hundreds);
		lcddispchar(tens);
		lcddispchar(ones);	
	}	
	else if (thousands!='0')
	{
		if (temp<0)
			lcddispchar('-');
		lcddispchar(thousands);
		lcddispchar(hundreds);
		lcddispchar(tens);
		lcddispchar(ones);	
	}
	else if (hundreds!='0')
	{
		if (temp<0)
			lcddispchar('-');
		lcddispchar(hundreds);
		lcddispchar(tens);
		lcddispchar(ones);	
	}
	else if (tens != '0')
	{
		if (temp<0)
			lcddispchar('-');
		lcddispchar(tens);
		lcddispchar(ones);
	}
	else
	{
		if (temp<0)
			lcddispchar('-');
		lcddispchar(ones);
	}
}

void lcddisp8bitbinary(int binary)
{
	//Displays a 8 bit binary number on the LCD
	int seven=0, six=0, five=0, four=0, three=0, two=0, one=0, zero=0;
	
	if ((binary & 0b00000001)==0b00000001) seven=1;
	if ((binary & 0b00000010)==0b00000010) six=1;
	if ((binary & 0b00000100)==0b00000100) five=1;
	if ((binary & 0b00001000)==0b00001000) four=1;
	if ((binary & 0b00010000)==0b00010000) three=1;
	if ((binary & 0b00100000)==0b00100000) two=1;
	if ((binary & 0b01000000)==0b01000000) one=1;
	if ((binary & 0b10000000)==0b10000000) zero=1;
	lcddispchar(zero+48);
	lcddispchar(one+48);
	lcddispchar(two+48);
	lcddispchar(three+48);
	lcddispchar(four+48);
	lcddispchar(five+48);
	lcddispchar(six+48);
	lcddispchar(seven+48);

}


void lcddispmsg(char msg[], int length)
{
	/*This function will take in an array
	of characters and display it on the LCD
	screen.  It will always clear the display
	and start in the top left of the display*/
	
	char temp;
	

	for (int i=0 ; i!=length; i++)      			 //Send Message to LCD
	{
		temp=msg[i];
		SEND_CHAR(temp);  
	}

}

void init_lcd(void)
{


	_delay_ms(100);               	               	
    LCD_Ini(); 					//LCD initialisation after reset     
    _delay_ms(10);  
//---------------------------------------------------
	SEND_CMD(DISP_ON);
	_delay_ms(10);  						
	SEND_CMD(CLR_DISP); 
 	_delay_ms(10);  


}


// appends string to lcd view
void write(char * str)
{
	lcddispmsg(str, strlen(str));
}


// prints new string to LCD view
void writeln(char * str)
{
	lcddispmsgnew(str, strlen(str));

}

